// --- Copyright (c) 2006-2008 Stefan Kyntchev ---
// This software is written and copyrighted by Stefan Kyntchev 
// and BeyondPod Team members. All rights are reserved.
// Author contact: support@beyondpod.mobi
// ------------------------------------------------------------------------
// This file is part of BeyondPod RSS Feed Reader and Podcast manager
// (www.codeplex.com/BeyondPod) 
// BeyondPod is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published by 
// the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
//  
// BeyondPod is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
// GNU General Public License for more details. 
//  
// You should have received a copy of the GNU General Public License
// along with BeyondPod. If not, see <http://www.gnu.org/licenses/>
// ------------------------------------------------------------------------
// COPYRIGHT NOTICE: This copyright notice may NOT be removed, obscured or modified 
// without written consent from the author.
// --- End copyright notice --- 


using System;
using System.Text.RegularExpressions;

namespace svs.Mobile.BeyondMedia.FeedCore.RSS.Entities
{
	public class RssFeedItem : IEquatable<RssFeedItem>
	{
		private string m_title;
		private string m_link;
		private DateTime? m_pubDate;
		private RssEnclosure m_enclosure;
		private readonly RssFeed m_parentFeed;
		private Guid? m_originatingFeedID;

		public RssFeedItem(RssFeed feed)
		{
			m_title = String.Empty;
			m_link = String.Empty;
			Description = String.Empty;
			Author = String.Empty;
			m_pubDate = null;
			Category = String.Empty;
			m_enclosure = null;
			m_parentFeed = feed;
		}

		public string Title
		{
			get { return m_title; }
			set { m_title = value; }
		}

		public string Link
		{
			get { return m_link; }
			set { m_link = value; }
		}

		public string Description { get; set; }


		public string TaglessDescription
		{
			get
			{
				return CleanHtmlTags(Description);
			}
		}

		private static string CleanHtmlTags(string description)
		{
			var regEx = new Regex("<[^>]*>", RegexOptions.IgnoreCase);
			return regEx.Replace(description,string.Empty);
		}

		public string Author { get; set; }

		public Guid OriginatingFeedID
		{
			get
			{
				return m_originatingFeedID.HasValue ? m_originatingFeedID.Value : m_parentFeed.FeedID;
			}

			set { m_originatingFeedID = value; }
		}

		/// <summary>
		/// Feed Published date in UTC
		/// </summary>
		public DateTime? PubDate
		{
			get { return m_pubDate; }
			set
			{
				m_pubDate = value;
			}
		}

		public string OriginalPubDateString { get; set; }

		public string Category { get; set; }

		public RssEnclosure Enclosure
		{
			get { return m_enclosure; } 
			set
			{
				m_enclosure = value;
				m_enclosure.Parent = this;
			}
		}

		//Marks teh feed as read or unread
		public bool Read
		{
			get
			{
				return ItemID.HasValue && ItemReadHistory.HasEntryFor(OriginatingFeedID, ItemID.Value);
			}
			set
			{
				if (!ItemID.HasValue)
					return;

				if(value)
					ItemReadHistory.AddItem(OriginatingFeedID, ItemID.Value);
				else
					ItemReadHistory.RemoveItem(OriginatingFeedID, ItemID.Value);

				if(OriginatingFeedID.Equals(m_parentFeed.FeedID))
						m_parentFeed.SyncOwnerFeedReadStatus();
				else
				{
					var owner = FeedRepository.GetFeedById(OriginatingFeedID);
					if(owner != null)
					{
						RssFeedCache.SyncFeedReadStatus(owner);
					}
				}
			}
		}

		public bool Equals(RssFeedItem rssFeedItem)
		{
			if (rssFeedItem == null) return false;
			if (!Equals(m_title, rssFeedItem.m_title)) return false;
			if (!Equals(m_link, rssFeedItem.m_link)) return false;
			if (!Equals(m_pubDate, rssFeedItem.m_pubDate)) return false;
			return true;
		}

		public override bool Equals(object obj)
		{
			if (ReferenceEquals(this, obj)) return true;
			return Equals(obj as RssFeedItem);
		}

		public override int GetHashCode()
		{
			int result = m_title != null ? m_title.GetHashCode() : 0;
			result = 29*result + (m_link != null ? m_link.GetHashCode() : 0);
			result = 29*result + (m_pubDate.HasValue? m_pubDate.Value.GetHashCode(): 0);
			return result;
		}

		/// <summary>
		/// A Unique ID of the item calculated by hashing the Item's title, link and pub date
		/// </summary>
		public int? ItemID
		{
			get
			{
				var h = GetHashCode();

				if(h == 0)
					return null;

				return h;
			}
		}
	}
}